home *** CD-ROM | disk | FTP | other *** search
/ Java Programmer's Toolkit / Java Programmer's Toolkit.iso / solaris2 / jdk / src / java / awt / image / rgbimage.jav < prev    next >
Encoding:
Text File  |  1995-10-30  |  8.1 KB  |  227 lines

  1. /*
  2.  * @(#)RGBImageFilter.java    1.8 95/09/08 Jim Graham
  3.  *
  4.  * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "copyright.html"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19.  
  20. package java.awt.image;
  21.  
  22. import java.awt.image.ImageConsumer;
  23. import java.awt.image.ColorModel;
  24.  
  25. /**
  26.  * This class provides an easy way to create a ImageFilter which modifies
  27.  * the pixels of an image in the default RGB ColorModel.  It is meant to
  28.  * be used in conjunction with a FilteredImageSource object to produce
  29.  * filtered versions of existing images.  It is an abstract class that
  30.  * provides the calls needed to channel all of the pixel data through a
  31.  * single method which converts pixels one at a time in the default RGB
  32.  * ColorModel regardless of the ColorModel being used by the ImageProducer.
  33.  * The only method which needs to be defined to create a useable image
  34.  * filter is the filterRGB method.  Here is an example of a definition
  35.  * of a filter which swaps the red and blue components of an image:
  36.  * <pre>
  37.  *
  38.  *    class RedBlueSwapFilter extends RGBImageFilter {
  39.  *        public RedBlueSwapFilter() {
  40.  *        // The filter's operation does not depend on the
  41.  *        // pixel's location, so IndexColorModels can be
  42.  *        // filtered directly.
  43.  *        canFilterIndexColorModel = true;
  44.  *        }
  45.  *
  46.  *        public int filterRGB(int x, int y, int rgb) {
  47.  *        return ((rgb & 0xff00ff00)
  48.  *            | ((rgb & 0xff0000) >> 16)
  49.  *            | ((rgb & 0xff) << 16));
  50.  *        }
  51.  *    }
  52.  *
  53.  * </pre>
  54.  *
  55.  * @see FilteredImageSource
  56.  * @see ImageFilter
  57.  * @see ColorModel#getRGBdefault
  58.  *
  59.  * @version    1.8 09/08/95
  60.  * @author     Jim Graham
  61.  */
  62. public abstract class RGBImageFilter extends ImageFilter {
  63.     protected ColorModel origmodel;
  64.     protected ColorModel newmodel;
  65.  
  66.     /**
  67.      * This boolean indicates whether or not it is acceptable to apply
  68.      * the color filtering of the filterRGB method to the color table
  69.      * entries of an IndexColorModel object in lieu of pixel by pixel
  70.      * filtering.  Subclasses should set this variable to true in their
  71.      * constructor if their filterRGB method does not depend on the
  72.      * coordinate of the pixel being filtered.
  73.      * @see #substituteColorModel
  74.      * @see #filterRGB
  75.      * @see IndexColorModel
  76.      */
  77.     protected boolean canFilterIndexColorModel;
  78.  
  79.     /**
  80.      * If the ColorModel is an IndexColorModel, and the subclass has
  81.      * set the canFilterIndexColorModel flag to true, then we substitute
  82.      * a filtered version of the color model here and whenever we see
  83.      * that original ColorModel object in the setPixels methods, otherwise
  84.      * we override the default ColorModel used by the ImageProducer and
  85.      * specify the default RGB ColorModel instead.
  86.      * @see ImageConsumer
  87.      * @see ColorModel#getRGBdefault
  88.      */
  89.     public void setColorModel(ColorModel model) {
  90.     if (canFilterIndexColorModel && (model instanceof IndexColorModel)) {
  91.         ColorModel newcm = filterIndexColorModel((IndexColorModel)model);
  92.         substituteColorModel(model, newcm);
  93.         consumer.setColorModel(newcm);
  94.     } else {
  95.         consumer.setColorModel(ColorModel.getRGBdefault());
  96.     }
  97.     }
  98.  
  99.     /**
  100.      * Register two ColorModel objects for substitution.  If the oldcm
  101.      * is encountered during any of the setPixels methods, then the newcm
  102.      * will be substituted for it and the pixels will be passed through
  103.      * untouched (but with the new ColorModel object).
  104.      * @param oldcm the ColorModel object to be replaced on the fly
  105.      * @param newcm the ColorModel object to replace oldcm on the fly
  106.      */
  107.     public void substituteColorModel(ColorModel oldcm, ColorModel newcm) {
  108.     origmodel = oldcm;
  109.     newmodel = newcm;
  110.     }
  111.  
  112.     /**
  113.      * Filter an IndexColorModel object by running each entry in its
  114.      * color tables through the filterRGB function that RGBImageFilter
  115.      * subclasses must provide.  Use coordinates of -1 to indicate that
  116.      * a color table entry is being filtered rather than an actual
  117.      * pixel value.
  118.      * @param icm the IndexColorModel object to be filtered
  119.      * @return a new IndexColorModel representing the filtered colors
  120.      */
  121.     public IndexColorModel filterIndexColorModel(IndexColorModel icm) {
  122.     byte r[] = new byte[256];
  123.     byte g[] = new byte[256];
  124.     byte b[] = new byte[256];
  125.     byte a[] = new byte[256];
  126.     icm.getReds(r);
  127.     icm.getGreens(g);
  128.     icm.getBlues(b);
  129.     icm.getAlphas(a);
  130.     int mapsize = icm.getMapSize();
  131.     for (int i = 0; i < mapsize; i++) {
  132.         int rgb = filterRGB(-1, -1, icm.getRGB(i));
  133.         a[i] = (byte) (rgb >> 24);
  134.         r[i] = (byte) (rgb >> 16);
  135.         g[i] = (byte) (rgb >> 8);
  136.         b[i] = (byte) (rgb >> 0);
  137.     }
  138.     return new IndexColorModel(icm.getPixelSize(), mapsize, r, g, b, a);
  139.     }
  140.  
  141.     /**
  142.      * Filter a buffer of pixels in the default RGB ColorModel by passing
  143.      * them one by one through the filterRGB method.
  144.      * @see ColorModel#getRGBdefault
  145.      * @see #filterRGB
  146.      */
  147.     public void filterRGBPixels(int x, int y, int w, int h,
  148.                 int pixels[], int off, int scansize) {
  149.     int index = off;
  150.     for (int cy = 0; cy < h; cy++) {
  151.         for (int cx = 0; cx < w; cx++) {
  152.         pixels[index] = filterRGB(x + cx, y + cy, pixels[index]);
  153.         index++;
  154.         }
  155.         index += scansize - w;
  156.     }
  157.     consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(),
  158.                pixels, off, scansize);
  159.     }
  160.  
  161.     /**
  162.      * If the ColorModel object is the same one that has already
  163.      * been converted, then simply pass the pixels through with the
  164.      * converted ColorModel, otherwise convert the buffer of byte
  165.      * pixels to the default RGB ColorModel and pass the converted
  166.      * buffer to the filterRGBPixels method to be converted one by one.
  167.      * @see ColorModel#getRGBdefault
  168.      * @see #filterRGBPixels
  169.      */
  170.     public void setPixels(int x, int y, int w, int h,
  171.               ColorModel model, byte pixels[], int off,
  172.               int scansize) {
  173.     if (model == origmodel) {
  174.         consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
  175.     } else {
  176.         int filteredpixels[] = new int[w];
  177.         int index = off;
  178.         for (int cy = 0; cy < h; cy++) {
  179.         for (int cx = 0; cx < w; cx++) {
  180.             filteredpixels[cx] = model.getRGB((pixels[index] & 0xff));
  181.             index++;
  182.         }
  183.         index += scansize - w;
  184.         filterRGBPixels(x, y + cy, w, 1, filteredpixels, 0, w);
  185.         }
  186.     }
  187.     }
  188.  
  189.     /**
  190.      * If the ColorModel object is the same one that has already
  191.      * been converted, then simply pass the pixels through with the
  192.      * converted ColorModel, otherwise convert the buffer of integer
  193.      * pixels to the default RGB ColorModel and pass the converted
  194.      * buffer to the filterRGBPixels method to be converted one by one.
  195.      * Convert a buffer of integer pixels to the default RGB ColorModel
  196.      * and pass the converted buffer to the filterRGBPixels method.
  197.      * @see ColorModel#getRGBdefault
  198.      * @see #filterRGBPixels
  199.      */
  200.     public void setPixels(int x, int y, int w, int h,
  201.               ColorModel model, int pixels[], int off,
  202.               int scansize) {
  203.     if (model == origmodel) {
  204.         consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
  205.     } else {
  206.         int filteredpixels[] = new int[w];
  207.         int index = off;
  208.         for (int cy = 0; cy < h; cy++) {
  209.         for (int cx = 0; cx < w; cx++) {
  210.             filteredpixels[cx] = model.getRGB(pixels[index]);
  211.             index++;
  212.         }
  213.         index += scansize - w;
  214.         filterRGBPixels(x, y + cy, w, 1, filteredpixels, 0, w);
  215.         }
  216.     }
  217.     }
  218.  
  219.     /**
  220.      * Subclasses must specify a method to convert a single input pixel
  221.      * in the default RGB ColorModel to a single output pixel.
  222.      * @see ColorModel#getRGBdefault
  223.      * @see #filterRGBPixels
  224.      */
  225.     public abstract int filterRGB(int x, int y, int rgb);
  226. }
  227.